#include "gtest/gtest.h"

#include <iostream>

#include "ioconnections.h"
#include "model.h"
#include "predictors/predictor_target.h"
#include "model_link.h"
#include "predictors/predictor_link.h"

using namespace std;

TEST(IOConnections, construct)
{
  Predictor_link l(INPUT);
  IConnection ic(&l);

  float value = 5;

  ic.set_name("my input link");

  ic.set_value_p(&value);

  ic.get_value();

  ASSERT_EQ("my input link", ic.get_name());
  ASSERT_EQ(5, l.get_value());
}

class T
{
public:
  T()
  {
    v = 0;
  }

  void set_value(float value)
  {
    v = value;
  }

  float get_value(void)
  {
    return v;
  }

  boost::function<void(float)> get_set_value_function(void)
  {
    return std::bind1st(std::mem_fun(&T::set_value), this);
  }

private:
  float v;
};

TEST(IOConnections, OConnection)
{
  Predictor_target p("TEST");

  p.get_input_link(0)->set_value(0.0); // set target
  p.get_input_link(1)->set_value(0.0); // set input

  p.predict(0.0);

  Model *model = new Model(&p);

  model->activate(1.0);
  model->activate_output_link();

  ASSERT_EQ(true, model->is_active());

  Model_link ml;
  ml.set_source(model);

  OConnection oc(&ml);

  oc.set_name("my output link");

  ASSERT_EQ("my output link", oc.get_name());

  // test bind function
  T a;

  oc.set_function(a.get_set_value_function());

  oc.set_value();

  ASSERT_EQ( 0.0, a.get_value());
}

